Many computer graphic images are created by mathematically modeling the interaction of light with a three-dimensional (3D) scene from a given viewpoint. This process, called “rendering,” generates a two-dimensional (2D) image of the scene from the given viewpoint, and is analogous to taking a photograph of a real-world scene.
As the demand for computer graphics, and in particular for real-time computer graphics, has increased, computer systems with graphics processing subsystems adapted to accelerate the rendering process have become widespread. In these computer systems, the rendering process is divided between a computer's general purpose central processing unit (CPU) and the graphics processing subsystem, architecturally centered about a graphics processing unit (GPU). Typically, the CPU performs high-level operations, such as determining the position, motion, and collision of objects in a given scene. From these high-level operations, the CPU generates a set of rendering commands and data defining the desired rendered image or images. For example, rendering commands and data can define scene geometry, lighting, shading, texturing, motion, and/or camera parameters for a scene. The graphics processing subsystem creates one or more rendered images from the set of rendering commands and data.
Scene geometry is typically represented by geometric primitives, such as points, lines, polygons (for example, triangles and quadrilaterals), and curved surfaces, defined by one or more two- or three-dimensional vertices. Each vertex may have additional scalar or vector attributes used to determine qualities such as the color, transparency, lighting, shading, and animation of the vertex and its associated geometric primitives. Scene geometry may also be approximated by a depth texture representing view-space Z coordinates of opaque objects covering each pixel.
Many graphics processing subsystems are highly programmable through an application programming interface (API), enabling complicated lighting and shading algorithms, among other things, to be implemented. To exploit this programmability, applications can include one or more graphics processing subsystem programs, which are executed by the graphics processing subsystem in parallel with a main program executed by the CPU. Although not confined merely to implementing shading and lighting algorithms, these graphics processing subsystem programs are often referred to as “shading programs,” “programmable shaders,” or simply “shaders.”
Many shading programs are executed in a stage of the “graphics pipeline” known as screen-space. Screen-space rendering is carried out pixel-by-pixel just before displaying a scene. Effects such as ambient occlusion, ambient illumination, depth-of-field, reflection and anti-aliasing are computationally expensive when performed during geometry rendering. In screen-space, complex geometries are decoupled from lighting phenomena, allowing screen-space shading programs to operate more efficiently with a minimal geometry data set. Screen-space rendering processes rely on data available in a geometry buffer, “G-buffer” or “frame buffer,” which is generated during geometry rendering and rasterizing.
The frame buffer generally lacks the complete geometry, or complexity, of a three-dimensional scene. The pixel-wise representation of the scene often includes only visible surfaces, or those being nearest in the depth field. Scenes reconstructed in screen-space (from the frame buffer) sometimes experience artifacts near geometric discontinuities. The artifacts manifest as incorrect reflections and color bleeding and disoriented shadowing, among others, and result from an inability to consider off-screen surfaces.
This limitation of screen-space rendering can be overcome by additional processing. One such technique is depth peeling. Conventional screen-space processes have access to only the first depth in the pixel-wise depth buffer (a portion of the frame buffer). When using depth peeling, the first k depth values are stored in the frame buffer during rendering. The additional complexity is easily stored in the frame buffer and gives occluding objects a depth dimension otherwise unavailable in the conventional depth buffer. Shadows cast by these occluding “volumes” are more visually plausible than their two-dimensional counterparts. A similar technique, akin to ray-marching, is to sample the depth field along a line extending radially from the pixel being shaded. Yet another technique is even more duplicative: multiple viewpoints or “cameras.” With multiple cameras, the scene is rendered from each camera, creating one or more largely redundant frame buffers to that of the primary viewpoint or “viewer camera.” Additional cameras are distinctly separated from the viewer camera, for instance, rotated ninety degrees (90°) with respect to the object center, i.e., orthogonal. Two, three or even four additional cameras allow frame buffers to be packed with enough data to reconstruct the scene with great detail.
Each of these techniques lengthens the shading process, whether by adding data to the frame buffer, which must be retrieved in screen-space, by increased sampling, or simply by duplicating frame buffers all-together. With increased processing bandwidth in GPUs, many consider this a modest tradeoff for improved shading results. In real-time rendering, screen-space techniques are still good alternatives to processing effects during geometry rendering.